package com.example.roundcornerprogressbar.view.progressbar;

import com.example.roundcornerprogressbar.ResourceTable;
import com.example.roundcornerprogressbar.view.progressbar.common.AnimatedRoundCornerProgressBar;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.utils.Parcel;
import ohos.utils.Sequenceable;
import org.jetbrains.annotations.Nullable;

import static ohos.agp.components.AttrHelper.vp2px;

public class IconRoundCornerProgressBar extends AnimatedRoundCornerProgressBar {
    protected final static int DEFAULT_ICON_SIZE = 20;
    protected final static int DEFAULT_ICON_PADDING_LEFT = 0;
    protected final static int DEFAULT_ICON_PADDING_RIGHT = 0;
    protected final static int DEFAULT_ICON_PADDING_TOP = 0;
    protected final static int DEFAULT_ICON_PADDING_BOTTOM = 0;

    private Image ivProgressIcon;
    private int iconResource;
    private int iconSize;
    private int iconWidth;
    private int iconHeight;
    private int iconPadding;
    private int iconPaddingLeft;
    private int iconPaddingRight;
    private int iconPaddingTop;
    private int iconPaddingBottom;
    private int colorIconBackground;

    private PixelMap iconBitmap;
    private Element iconDrawable;

    private OnIconClickListener iconClickListener;

    public IconRoundCornerProgressBar(Context context) {
        super(context);
    }

    public IconRoundCornerProgressBar(Context context, AttrSet attrSet) {
        super(context, attrSet);
    }

    public IconRoundCornerProgressBar(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
    }

    @Override
    protected int initLayout() {
        return ResourceTable.Layout_layout_icon_round_corner_progress_bar;
    }

    @Override
    protected void initStyleable(Context context, AttrSet attrs) {
        iconResource = -1;
        iconSize = -1;
        iconWidth = vp2px(DEFAULT_ICON_SIZE, context);
        iconHeight = vp2px(DEFAULT_ICON_SIZE, context);
        iconPadding = -1;
        iconPaddingLeft = vp2px(DEFAULT_ICON_PADDING_LEFT, context);
        iconPaddingRight = vp2px(DEFAULT_ICON_PADDING_RIGHT, context);
        iconPaddingTop = vp2px(DEFAULT_ICON_PADDING_TOP, context);
        iconPaddingBottom = vp2px(DEFAULT_ICON_PADDING_BOTTOM, context);
        try {
            colorIconBackground = getResourceManager().getElement(ResourceTable.Color_round_corner_progress_bar_background_default).getColor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void initView() {
        ivProgressIcon = (Image) findComponentById(ResourceTable.Id_iv_progress_icon);
        ivProgressIcon.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (iconClickListener != null) {
                    iconClickListener.onIconClick();
                }
            }
        });
    }

    public void setOnIconClickListener(@Nullable OnIconClickListener listener) {
        iconClickListener = listener;
    }

    @Override
    protected void drawProgress(DirectionalLayout layoutProgress,
                                ShapeElement progressDrawable,
                                float max,
                                float progress,
                                float totalWidth,
                                int radius,
                                int padding,
                                boolean isReverse) {
        int newRadius = radius - (padding / 2);
        if (isReverse && progress != max) {
            progressDrawable.setCornerRadiiArray(new float[]{newRadius, newRadius, newRadius, newRadius, newRadius, newRadius, newRadius, newRadius});
        } else {
            progressDrawable.setCornerRadiiArray(new float[]{0, 0, newRadius, newRadius, newRadius, newRadius, 0, 0});
        }
        layoutProgress.setBackground(progressDrawable);

        float ratio = max / progress;
        int progressWidth = (int) ((totalWidth - ((padding * 2) + ivProgressIcon.getWidth())) / ratio);
        ComponentContainer.LayoutConfig progressParams = (ComponentContainer.LayoutConfig)layoutProgress.getLayoutConfig();
        if (isReverse) {
            if (padding + (progressWidth / 2) < radius) {
                int margin = Math.max(radius - padding, 0) - (progressWidth / 2);
                progressParams.setMarginTop(margin);
                progressParams.setMarginBottom(margin);
            } else {
                progressParams.setMarginTop(0);
                progressParams.setMarginBottom(0);
            }
        }
        progressParams.width = progressWidth;
        layoutProgress.setLayoutConfig(progressParams);
    }

    @Override
    protected void onViewDraw() {
        drawImageIcon();
        drawImageIconSize();
        drawImageIconPadding();
        drawIconBackgroundColor();
    }

    private void drawImageIcon() {
        if (iconResource != -1) {
            ivProgressIcon.setPixelMap(iconResource);
        } else if (iconBitmap != null) {
            ivProgressIcon.setPixelMap(iconBitmap);
        } else if (iconDrawable != null) {
            ivProgressIcon.setImageElement(iconDrawable);
        }
    }

    private void drawImageIconSize() {
        if (iconSize == -1) {
            ivProgressIcon.setLayoutConfig(new ComponentContainer.LayoutConfig(iconWidth, iconHeight));
        } else {
            ivProgressIcon.setLayoutConfig(new ComponentContainer.LayoutConfig(iconSize, iconSize));
        }
    }

    private void drawImageIconPadding() {
        if (iconPadding == -1 || iconPadding == 0) {
            ivProgressIcon.setPadding(iconPaddingLeft, iconPaddingTop, iconPaddingRight, iconPaddingBottom);
        } else {
            ivProgressIcon.setPadding(iconPadding, iconPadding, iconPadding, iconPadding);
        }
        ivProgressIcon.invalidate();
    }

    private void drawIconBackgroundColor() {
        ShapeElement iconBackgroundDrawable = createGradientDrawable(RgbColor.fromArgbInt(colorIconBackground));
        int radius = getRadius() - (getBasePadding() / 2);
        iconBackgroundDrawable.setCornerRadiiArray(new float[]{radius, radius, 0, 0, 0, 0, radius, radius});
        ivProgressIcon.setBackground(iconBackgroundDrawable);
    }

    public int getIconImageResource() {
        return iconResource;
    }

    public void setIconImageResource(int resId) {
        this.iconResource = resId;
        this.iconBitmap = null;
        this.iconDrawable = null;
        drawImageIcon();
    }

    public PixelMap getIconImageBitmap() {
        return iconBitmap;
    }

    public void setIconImageBitmap(PixelMap bitmap) {
        this.iconResource = -1;
        this.iconBitmap = bitmap;
        this.iconDrawable = null;
        drawImageIcon();
    }

    public Element getIconImageDrawable() {
        return iconDrawable;
    }

    public void setIconImageDrawable(Element drawable) {
        this.iconResource = -1;
        this.iconBitmap = null;
        this.iconDrawable = drawable;
        drawImageIcon();
    }

    public int getIconSize() {
        return iconSize;
    }

    public void setIconSize(int size) {
        if (size >= 0) {
            this.iconSize = size;
        }
        drawImageIconSize();
    }

    public int getIconPadding() {
        return iconPadding;
    }

    public void setIconPadding(int padding) {
        if (padding >= 0) {
            this.iconPadding = padding;
        }
        drawImageIconPadding();
    }

    public int getIconPaddingLeft() {
        return iconPaddingLeft;
    }

    public void setIconPaddingLeft(int padding) {
        if (padding > 0) {
            this.iconPaddingLeft = padding;
        }
        drawImageIconPadding();
    }

    public int getIconPaddingRight() {
        return iconPaddingRight;
    }

    public void setIconPaddingRight(int padding) {
        if (padding > 0) {
            this.iconPaddingRight = padding;
        }
        drawImageIconPadding();
    }

    public int getIconPaddingTop() {
        return iconPaddingTop;
    }

    public void setIconPaddingTop(int padding) {
        if (padding > 0) {
            this.iconPaddingTop = padding;
        }
        drawImageIconPadding();
    }

    public int getIconPaddingBottom() {
        return iconPaddingBottom;
    }

    public void setIconPaddingBottom(int padding) {
        if (padding > 0) {
            this.iconPaddingBottom = padding;
        }
        drawImageIconPadding();
    }

    public int getColorIconBackground() {
        return colorIconBackground;
    }

    public void setIconBackgroundColor(int color) {
        this.colorIconBackground = color;
        drawIconBackgroundColor();

    }

//    @Override
//    protected Parcelable onSaveInstanceState() {
//       android.vSaveInstanceState onRestoreInstanceState 使用postLayout()???
//    }
//    @Override
//    protected void onRestoreInstanceState(Parcelable state) {
//
//    }

    public interface OnIconClickListener {
        void onIconClick();
    }

    protected static class SavedState implements Sequenceable {
        int iconResource;
        int iconSize;
        int iconWidth;
        int iconHeight;
        int iconPadding;
        int iconPaddingLeft;
        int iconPaddingRight;
        int iconPaddingTop;
        int iconPaddingBottom;
        int colorIconBackground;

        @Override
        public boolean marshalling(Parcel out) {
            return out.writeFloat(this.iconResource) &&
                    out.writeFloat(this.iconSize) &&
                    out.writeFloat(this.iconWidth) &&
                    out.writeInt(this.iconHeight) &&
                    out.writeInt(this.iconPadding) &&
                    out.writeInt(this.iconPaddingLeft) &&
                    out.writeInt(this.iconPaddingRight) &&
                    out.writeInt(this.iconPaddingTop) &&
                    out.writeInt(this.iconPaddingBottom) &&
                    out.writeInt(this.colorIconBackground) ;
        }

        @Override
        public boolean unmarshalling(Parcel in) {
            this.iconResource = in.readInt();
            this.iconSize = in.readInt();
            this.iconWidth = in.readInt();
            this.iconHeight = in.readInt();
            this.iconPadding = in.readInt();
            this.iconPaddingLeft = in.readInt();
            this.iconPaddingRight = in.readInt();
            this.iconPaddingTop = in.readInt();
            this.iconPaddingBottom = in.readInt();
            this.colorIconBackground = in.readInt();
            return true;
        }

        public static final Sequenceable.Producer PRODUCER = new Sequenceable.Producer() {

            @Override
            public SavedState createFromParcel(Parcel in) {
                SavedState instance = new SavedState();
                instance.unmarshalling(in);
                return instance;
            }
        };
    }
}
